package org.github.manx98.jlibhac.fssystem;

import cn.hutool.core.util.StrUtil;
import org.github.manx98.jlibhac.fs.IStorage;
import org.github.manx98.jlibhac.fs.SubStorage;
import org.github.manx98.jlibhac.fs.fsa.*;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

public class PartitionFileSystem extends IFileSystem {
    public final PartitionFileSystemHeader Header;
    public final int HeaderSize;
    public final PartitionFileEntry[] Files;
    public final Map<String, PartitionFileEntry> FileDict = new HashMap<>();
    private final IStorage baseStorage;

    public PartitionFileSystem(IStorage reader) throws IOException {
        Header = new PartitionFileSystemHeader(reader.asStorage());
        HeaderSize = Header.HeaderSize;
        Files = Header.Files;
        for (PartitionFileEntry file : Files) {
            FileDict.put(file.name, file);
        }
        this.baseStorage = reader;
    }

    public void GetGameData(PartitionFileSystemHeader pfs) {

    }

    public IFile doOpenFile(String path, OpenMode mode) throws IOException {
        PartitionFileEntry entry = FileDict.get(StrUtil.removePrefix(path, "/"));
        if (entry == null) {
            throw new FileNotFoundException("file not exist: " + path);
        }
        return openPartitionFileEntry(entry);
    }

    @Override
    public IDirectory doOpenDirectory(String path, OpenDirectoryMode mode) throws IOException{
        path = StrUtil.removePrefix(path, "/");
        return new PartitionDirectory(this, path, mode);
    }

    public IFile openPartitionFileEntry(PartitionFileEntry entry) throws IOException {
        return new PartitionFile(baseStorage, HeaderSize + entry.offset, entry.size);
    }

    public List<PartitionFileEntry> enumerateEntries(String match) throws IOException {
        List<PartitionFileEntry> files = new ArrayList<>();
        Pattern compile = Pattern.compile(match);
        for (PartitionFileEntry file : Files) {
            if (compile.matcher(file.name).matches()) {
                files.add(file);
            }
        }
        return files;
    }
}
